import junit.framework.TestCase;


public class MeasurementTest extends TestCase {

	public MeasurementTest(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		
		try {
			super.setUp();//TODO some setup;
			
		}catch(RuntimeException e){
			fail ("fail to generate new objects");
		}
			
		
		
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}
	/* Test the Measurement constructor with no argument.
	 * if toString() returns 0"0', function is confirmed to be working. 
	 */
	public final void testMeasurement() throws Exception {
		Measurement m1 = new Measurement();	
		assertEquals("Constructor() doesn't work","0\"0'",m1.toString());
		
		
	}
	/* Test the Measurement constructor with 1 argument.
	 * There are 4 test cases. 0 and 1 tests the behavior of method on
	 * the "edge" condition. 10 and 9999 tests the how method behave
	 * when there are multiple digits 
	 */
	public final void testMeasurementInt() throws Exception {
		Measurement m1 = new Measurement(0);	
		assertEquals("Constructor(0) doesn't work","0\"0'",m1.toString());
		m1 = new Measurement(1);
		assertEquals("Constructor(1) doesn't work","1\"0'",m1.toString());
		m1 = new Measurement(10);
		assertEquals("Constructor(10) doesn't work","10\"0'",m1.toString());
		m1 = new Measurement(9999);
		assertEquals("Constructor(9999) doesn't work","9999\"0'",m1.toString());		
	}

	/* Test the Measurement constructor with 2 arguments.
	 * There are 4 test cases. (0,0) and (1,1) tests the behavior of method on
	 * the "edge" condition. (1,13) and (2,220) tests the how method behave
	 * when there are one or more carry-ins.
	 */
	public final void testMeasurementIntInt()throws Exception {
		Measurement m1 = new Measurement(0,0);	
		assertEquals("Constructor(0,0) doesn't work","0\"0'",m1.toString());
		m1 = new Measurement(1,1);
		assertEquals("Constructor(1,1) doesn't work","1\"1'",m1.toString());
		m1 = new Measurement(0,12);
		assertEquals("Constructor(0,12) doesn't work","1\"0'",m1.toString());
		m1 = new Measurement(1,13);
		assertEquals("Constructor(1,13) doesn't work","2\"1'",m1.toString());
		m1 = new Measurement(2,120);
		assertEquals("Constructor(2,120) doesn't work","12\"0'",m1.toString());
		
	}

	/* Test the Measurement plus.
	 * There are 3 test cases. (0,0)+(0,0) and (0,0)+(1,1) tests the behavior of method on
	 * the "edge" condition. (1,0) + (1,1) tests the how method behave
	 * when there are carry-ins.
	 */
	public final void testPlus() throws Exception{
		Measurement m1 = new Measurement (0,0);
		Measurement m2 ;
		assertTrue("0\"0'+0\"0' failed",(m1.plus(m1)).toString().equals((new Measurement (0,0)).toString()));
		m2 = new Measurement (1,1);
		assertTrue("0\"0'+1\"1' failed",(m1.plus(m2)).toString().equals((new Measurement (1,1)).toString()));
		m1 = new Measurement (1,10);
		m2 = new Measurement (1,3);
		assertTrue("1\"10'+1\"3' failed",(m1.plus(m2)).toString().equals((new Measurement (3,1)).toString()));
		
	}

	/* Test the Measurement minus.
	 * There are 3 test cases. (0,0)-(0,0) and (1,1)-(0,0) tests the behavior of method on
	 * the "edge" condition. (1,10) - (0,11) tests the how method behave
	 * when there are borrow outs.
	 */
	public final void testMinus() throws Exception{
		Measurement m1 = new Measurement (0,0);
		Measurement m2 ;
		assertTrue("0\"0'-0\"0' failed",(m1.minus(m1)).toString().equals((new Measurement (0,0)).toString()));
		m2 = new Measurement (1,1);
		assertTrue("1\"1'-0\"0' failed",(m1.minus(m2)).toString().equals((new Measurement (1,1)).toString()));
		m1 = new Measurement (1,10);
		m2 = new Measurement (0,11);
		assertTrue("1\"10'-0\"11' failed",(m1.minus(m2)).toString().equals((new Measurement (0,11)).toString()));
	}
	/* Test the Measurement multiple.
	 * There are 3 test cases. (0,0)*0 and (1,1)*0 test the behavior of method on
	 * the "edge" condition. (1,1)*1 and (1,1)*2 test the how method behave
	 * when there are no carry in. (1,4)*4 and (1,4)*100 test the method on condition of 
	 * on or more carry in(s).
	 */
	public void testMultiple()throws Exception {
		Measurement m1 = new Measurement (0,0);
		int i = 0;
		assertTrue ("0\"0'*0 failed",(m1.multiple(i)).toString().equals((new Measurement (0,0)).toString()));
		m1 = new Measurement (1,1);
		assertTrue ("1\"1'*0 failed",(m1.multiple(i)).toString().equals((new Measurement (0,0)).toString()));
		i = 1;
		assertTrue ("1\"1'*1 failed",(m1.multiple(i)).toString().equals((new Measurement (1,1)).toString()));
		i = 2;
		assertTrue ("1\"1'*2 failed",(m1.multiple(i)).toString().equals((new Measurement (1,1)).toString()));
		m1 = new Measurement (1,4);
		i = 4;
		assertTrue ("1\"4'*4 failed",(m1.multiple(i)).toString().equals((new Measurement (5,4)).toString()));
		i = 100;;
		assertTrue ("1\"4'*100 failed",(m1.multiple(i)).toString().equals((new Measurement (133,4)).toString()));
	}

	/*
	 * This tests has 3 simple cases. It tests the functionality of toString() in the Measurement Class.
	 * If this method fails, then the other tests are unlikely to pass. The outcome of this method should
	 * be like f"i'.
	 */
	public final void testToString() throws Exception {
		
		
		assertTrue(new Measurement (0,0).toString().equals("0\"0'"));
		assertTrue(new Measurement (1,1).toString().equals("1\"1'"));
		assertTrue(new Measurement (2,2).toString().equals("2\"2'"));
	}

}
